using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Media.Imaging;

using MicroFractal.iTunesBrowser.Business;
using MicroFractal.iTunesBrowser.Core.Device;
using MicroFractal.iTunesBrowser.Core.Data.ITunesDB.Item;

namespace MicroFractal.iTunesBrowser.Core.Data.ITunesDB
{
    class ITunesDBParser : DbParser
    {

        #region Constructor

        public ITunesDBParser(IDevice device, MemoryStream file)
            : base(device, file)
        { }

        #endregion

        #region attributes

        private const int K_TrackList = 1;
        private const int K_Playlists = 2;
        private const int K_PodcastList = 3;
        private const int K_AlbumList = 4;
        private const int K_SmartPlaylist = 5;

        #endregion

        #region Overrides Methods

        public override MicroFractal.iTunesBrowser.Business.Library GetLibrary()
        {
            Library l = new Library();

            ITunesDB db = new ITunesDB(_file);
            foreach (ITunesDataSet ds in db.ITunesDataSets)
            {
                foreach (Item.DataItem it in ds.ItemList.Items)
                {
                    AddToLibrary(l, it);
                }
            }

            // l.Songs = GetSection(K_TrackList);

            return l;
        }

        #endregion

        #region Private Methods

        private void AddToLibrary(Library lib, Item.DataItem data)
        {
            if (data is TrackItem)
            {
                AddSong(lib, data as TrackItem);
            }
            else if (data is AlbumItem)
            {
                AddAlbum(lib, data as AlbumItem);
            }
        }

        private Song AddSong(Library lib, Item.TrackItem data)
        {
            Album a = AddAlbum(lib, data[StringDataTypeEnum.TrackArtist], data[StringDataTypeEnum.TrackAlbum]);
            Genre g = AddGenre(lib, data[StringDataTypeEnum.Genre]);
            Song s = new Song(data[StringDataTypeEnum.Title], a);
            s.Artist = a.Artist;
            s.Genre = g;
            s.Location = data[StringDataTypeEnum.Location];
            s.HasCover = data.HasCover;

            LoadCover(_device, a, s);

            s.Duration = new TimeSpan(0, 0, 0, 0, data.Duration);
            s.SongNumber = data.TrackNumber;

            lib.Songs.Add(s);
            return s;
        }

        private Album AddAlbum(Library lib, AlbumItem data)
        {
            return AddAlbum(lib, data[StringDataTypeEnum.Artist], data[StringDataTypeEnum.Album]);
        }

        private Album AddAlbum(Library lib, string artist, string albumName)
        {
            Artist art = AddArtist(lib, artist);
            Album a = new Album(albumName, art);

            if (lib.Albums.Contains(a))
                return lib.Albums[lib.Albums.IndexOf(a)];
            else
            {
                lib.Albums.Add(a);
                return a;
            }
        }

        private Artist AddArtist(Library lib, string name)
        {
            Artist a = new Artist(name);
            if (lib.Artists.Contains(a))
                return lib.Artists[lib.Artists.IndexOf(a)];
            else
            {
                lib.Artists.Add(a);
                return a;
            }
        }

        private Genre AddGenre(Library lib, string name)
        {
            if (string.IsNullOrEmpty(name))
                return null;

            Genre g = new Genre(name);
            if (lib.Genres.Contains(g))
                return lib.Genres[lib.Genres.IndexOf(g)];
            else
                lib.Genres.Add(g);

            return g;
        }

        private void LoadCover(IDevice device, Album album, Song song)
        {
            if (album.Cover == null && !string.IsNullOrEmpty(song.Location) && song.HasCover)
            {
                try
                {
                    TagLib.File f = null;
                    if (device.CanDirectlyAccessFiles)
                        f = TagLib.File.Create(device.GetFilePath(song));
                    else
                    {
                        string p = Path.GetTempPath();
                        if (!File.Exists(p + "\\" + device.GetSongFileName(song)))
                        {
                            List<IDownloadableObject> d = new List<IDownloadableObject>();
                            d.Add((IDownloadableObject)song);
                            if (device.Download(d, p, false) == 1)
                                f = TagLib.File.Create(p + "\\" + device.GetSongFileName(song));
                        }
                        else
                            f = TagLib.File.Create(p + "\\" + device.GetSongFileName(song));
                    }

                    if (f == null)
                        return;

                    TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)f.GetTag(TagLib.TagTypes.Id3v2);
                    if (tag != null)
                    {
                        TagLib.Id3v2.Frame[] frames = tag.GetFrames("APIC");

                        if (frames.Length > 0)
                        {

                            TagLib.Id3v2.AttachedPictureFrame at = (TagLib.Id3v2.AttachedPictureFrame)frames[0];
                            BitmapImage i = new BitmapImage();
                            i.BeginInit();
                            i.StreamSource = new System.IO.MemoryStream(at.Data.Data);
                            i.EndInit();
                            album.Cover = i;

                        }
                    }
                }
                catch { }
            }
        }

        #endregion

    }
}
